// 将axios二次封装
// 每个实例的拦截器和其他人无关 ，如果使用全局的实例，那么给每次请求单独配置拦截器就做不到
import config from '@/config'
import axios from 'axios'
import { getLocal } from '@/utils/local'

class HttpRequest {
    constructor () {
        // 可以增加实例属性 后台接口的路径 开发模式和生产模式不一样 在config里新建index.js进行配置
        this.baseURL = config.baseURL;// 默认地址
        this.timeout = 3000;// 3s后请求超时
    }

    setInterceptors (instance) { // 创建单独的拦截器
        instance.interceptors.request.use(config => {
            // 一般增加一些token属性等  jwt
            config.headers.authorization = 'Bearer ' + getLocal('token')
            return config;
        });
        instance.interceptors.response.use(res => {
            if (res.status === 200) {
                // 服务返回的结果都会放到data中
                if (res.data.err === 0) { // 统一处理错误状态码
                    console.log(res.data, 'res.data')
                    return Promise.resolve(res.data);// 成功状态
                } else {
                    return Promise.reject(res.data.data);// 失败状态
                }
            } else {
                return Promise.reject(res.data); // 我的后端实现的话 如果失败了会在返回的结果中增加一个data字段 失败的原因
            }
        }, err => {
            // 单独处理其他的状态码异常
            switch (err.response.status) {
            case '401':
                console.log(err)
                break;

            default:
                break;
            }
            return Promise.reject(err)
        })
    }

    mergeOptions (options) { // 合并选项
        return { baseURL: this.baseURL, timeout: this.timeout, ...options }
    }

    request (options) {
        const instance = axios.create()// 创建axios实例
        this.setInterceptors(instance)// 创建单独的拦截器
        const opts = this.mergeOptions(options)// 合并选项
        return instance(opts)// 单独拦截器的配置项
    }

    get (url, config) { // get请求  以字符串的形式传入 路径参数 ?a=1
        return this.request({
            method: 'get',
            url,
            ...config// 参数可以直接展开
        })
    }

    post (url, data) { // post请求 数据在请求中 {}
        return this.request({
            method: 'post',
            url,
            data: data // post要求必须传入data属性
        })
    }
}

export default new HttpRequest();
